package jmind.core.dubbo.callback;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

import jmind.core.dubbo.pojo.BusEvent;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.dubbo.rpc.RpcContext;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

public class CallbackServiceImpl implements ICallbackService {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final Multimap<String, Callback> listeners = HashMultimap.create();

    private final BiMap<Callback, String> map = HashBiMap.create();

    public void addListener(String key, Callback callback) {
        listeners.put(key, callback);
        String remote = RpcContext.getContext().getRemoteAddressString();
        map.put(callback, key + remote);
        logger.info("addListener key={},remote={}", key, remote);
    }

    // 立即执行不缓存
    public void addEvent(BusEvent event) {
        logger.info("addEvent event={},remote={}", event, RpcContext.getContext().getRemoteAddressString());
        Collection<Callback> collection = listeners.get(event.getTopic());
        if (collection.isEmpty()) {
            logger.info("event is empty {}", event);
        } else {
            Iterator<Callback> it = collection.iterator();
            Callback callback = null;
            while (it.hasNext()) {
                try {
                    callback = it.next();
                    boolean b = callback.doIt(event);
                    logger.info("doit addEvent {},result={} ", map.get(callback), b);
                } catch (com.alibaba.dubbo.rpc.RpcException e) {
                    logger.error("doit event={},{}", event, e);
                    it.remove();
                    map.remove(callback);
                }
            }
        }

    }

    public Set<String> getRemotes() {
        return map.values();
    }
}
